package com.kf.aop;

import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.Objects;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.kf.config.SecurityUser;
import com.kf.controller.LoginController;
import com.kf.mapper.LogLoginMapper;
import com.kf.mapper.LogSysOperationMapper;

import com.kf.pojo.LogLogin;
import com.kf.pojo.LogSysOperation;
import com.kf.pojo.User;
import com.kf.pojo.form.UserForm;


import com.kf.util.JsonUtils;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;



/**
 * 系统日志切面
 * 代理模式
 * @author CL
 *
 */
@Aspect
@Component
public class SysLogAspect {




	@Resource
	LogSysOperationMapper logSysOperationMapper;

	@Resource
	LogLoginMapper logLoginMapper;




	@Pointcut("@annotation(com.kf.aop.LogOperation)")
	public void logPointCut() {

	}

	public static ThreadLocal<LogSysOperation> stringThreadLocal1 = new ThreadLocal<>();

	@Around("logPointCut()")
	@Order(1)
	public Object around(ProceedingJoinPoint point) throws Throwable{
		long beginTime = System.currentTimeMillis();
		try {
//			saveLog(point,);
			//执行方法
//			long time = System.currentTimeMillis() - beginTime;
			logoutLog(point);
			Object result = point.proceed();
			//执行时长(毫秒)
			long time = System.currentTimeMillis() - beginTime;
			//保存日志
			saveLog(point,time,1);
			return result;
		}catch(Throwable e) {
			//执行时长(毫秒)
			System.out.println("我在aop捕获到了异常");
			Throwable cause = e.getCause();
			if(cause instanceof java.sql.SQLIntegrityConstraintViolationException){
				throw new SQLException();
			}
			throw e;
		}finally {
			long time = System.currentTimeMillis() - beginTime;

			try {
				LogSysOperation save = save(point, time, 0);
				stringThreadLocal1.set(save);
			} catch (Exception e) {
				throw e;
			}

		}
	}



	public LogSysOperation save(JoinPoint joinPoint,long time,int status) throws NoSuchMethodException {
		HttpServletRequest request = ((ServletRequestAttributes) Objects
				.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
		LogSysOperation sysLog1 = new LogSysOperation();
		User user = SecurityUser.getUser();
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
		LogOperation annotation = method.getAnnotation(LogOperation.class);
		Object[] args = joinPoint.getArgs();
		if(annotation != null&& !"登录".equals(annotation.value()) && !"退出".equals(annotation.value())){

			sysLog1.setOperation(annotation.value());
			if(args.length>0){
				String string = JsonUtils.toJsonString(args[0]);
				String pass="password";
				if(string.contains(pass)){
					String params = dePassword(string);
					sysLog1.setRequestParams(params);
				}else{
					sysLog1.setRequestParams(JsonUtils.toJsonString(args[0]));
				}
			}else{
				sysLog1.setRequestParams(null);
			}
			sysLog1.setIp(request.getServerName() + ":" + request.getServerPort());
			sysLog1.setRequestMethod(request.getMethod());
			sysLog1.setRequestUri(request.getRequestURI());
			sysLog1.setRequestUser(user.getUsername());
			sysLog1.setRequestTime((int)(time));
			sysLog1.setStatus(status);
		}

		return sysLog1;

	}

	public String dePassword(String string){
		String[] passwords = string.split("password");
		String[] split1 = passwords[0].split(",");
		String s1=split1[0];
		for (int i = 1; i < split1.length-1; i++) {
			s1=s1+","+split1[i];
		}
		String s = null;
		String[] split = passwords[1].split(",");
		s=split[1];
		for (int i = 2; i < split.length; i++) {
			s=s+","+split[i];
		}

		System.out.println(s1+","+s);
		return s1+",\"password\":\"*****\","+s;

	}

	private void saveLog(JoinPoint joinPoint,long time,int status) throws Exception {
		HttpServletRequest request = ((ServletRequestAttributes) Objects
				.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
		User user = SecurityUser.getUser();
		LogSysOperation sysLog = new LogSysOperation();
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
		LogOperation annotation = method.getAnnotation(LogOperation.class);
		Object[] args = joinPoint.getArgs();
		if(annotation != null&& !"登录".equals(annotation.value()) && !"退出".equals(annotation.value())&&!"手机登录".equals(annotation.value())){
			sysLog.setOperation(annotation.value());
			if(args.length>0){
				String string = JsonUtils.toJsonString(args[0]);
				String pass="password";
				if(string.contains(pass)){
					String params = dePassword(string);
					sysLog.setRequestParams(params);
				}else{
					sysLog.setRequestParams(JsonUtils.toJsonString(args[0]));
				}
			}else{
				sysLog.setRequestParams(null);
			}
//			sysLog.setRequestParams(JsonUtils.toJsonString(args[0]));
//			request.getScheme() + "://" +
			sysLog.setIp( request.getServerName() + ":" + request.getServerPort());
			sysLog.setRequestMethod(request.getMethod());
			sysLog.setRequestUri(request.getRequestURI());
			sysLog.setRequestUser(user.getUsername());
			sysLog.setRequestTime((int)(time));
			sysLog.setStatus(status);
			logSysOperationMapper.insert(sysLog);
			System.out.println("12312");

		}else if(annotation != null&& "登录".equals(annotation.value())){
			UserForm userForm = LoginController.stringThreadLocal.get();
			LogLogin logLogin = new LogLogin();
			logLogin.setIp(request.getServerName() + ":" + request.getServerPort());
			logLogin.setOperation(1);
			logLogin.setLoginUsername(userForm.getUsername());
			logLogin.setStatus(userForm.getStatus());
			System.out.println("我用ThreadLocal的信息是："+userForm);
			LoginController.stringThreadLocal.remove();
			logLoginMapper.insert(logLogin);

		}else if(annotation != null&&"手机登录".equals(annotation.value())){

			UserForm userForm = LoginController.stringThreadLocal.get();

			if(!"no".equals(userForm.getUsername())){

				LogLogin logLogin = new LogLogin();
				logLogin.setIp(request.getServerName() + ":" + request.getServerPort());
				logLogin.setOperation(1);
				logLogin.setLoginUsername(userForm.getUsername());
				logLogin.setStatus(userForm.getStatus());
				System.out.println("我用ThreadLocal的信息是："+userForm);
				LoginController.stringThreadLocal.remove();
				logLoginMapper.insert(logLogin);
			}

		}

	}

	public void logoutLog(ProceedingJoinPoint point) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) Objects
				.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
		System.out.println("我是before");
		MethodSignature signature = (MethodSignature) point.getSignature();
		Method method = point.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
		LogOperation annotation = method.getAnnotation(LogOperation.class);
		if (annotation != null && "退出".equals(annotation.value())) {
			LogLogin logLogin = new LogLogin();
			User loginUser = (User)request.getSession().getAttribute("loginUser");
			logLogin.setIp(request.getServerName() + ":" + request.getServerPort());
			logLogin.setOperation(0);
			logLogin.setLoginUsername(loginUser.getUsername());
			logLogin.setStatus(1);
			logLoginMapper.insert(logLogin);
		}
	}


}